GDB学习总结 快速入门 精华汇总 您所在的位置:网站首页 esp32快速入门 AT指令 GDB学习总结 快速入门 精华汇总

GDB学习总结 快速入门 精华汇总

2023-07-07 14:27| 来源: 网络整理| 查看: 265

1、说明

gdb -v 查看是否安装gdb

gcc main.c -o main.exe -g      ;-o = -o0 优化级别 -g产生gdb可用的exe

2、调用gdb的方式 2.1、调试尚未执行的程序

gdb main.exe

此时会创建两个进程:gdb调试器进程,程序本身的进程

包含入参的gdb调试

gdb --args ./main.exe para

2.2、调试正在执行的程序

为了方便管理当前系统中运行的诸多进程,每个进程都配有唯一的进程号(PID)

 ./main.exe

pidof main.exe

gdb attach PID

当 GDB 调试器成功连接到指定进程上时,程序执行会暂停

当调试完成后,如果想令当前程序继续执行,消除调试操作对它的影响,需手动将 GDB 调试器与程序分离

执行 detach 指令,使 GDB 调试器和程序分离;

执行 quit(或 q)指令,退出 GDB 调试。

2.3、调试执行异常崩溃的程序

 Linux 操作系统中,当程序执行发生异常崩溃时,系统可以将发生崩溃时的内存数据、调用堆栈情况等信息自动记录下载,并存储到一个文件中,该文件通常称为 core 文件;Linux 系统所具备的这种功能又称为核心转储(core dump)

ulimit -a 指令来查看当前系统是否开启此功能

为0 表示未开启core dump,使用下面的指令开启此功能

ulimit -c unlimited

默认情况下,core 文件的生成位置同该程序所在的目录相同;

gdb main.exe core 启动调试:现场恢复

GDB 对 core 文件的分析和调试提供有非常强大的功能支持

野指针举例

段错误又称为访问权限冲突,指的是当前程序访问了不可访问的存储空间,比如访问的不存在的空间,又或者是受系统保护的内存空间

 3、gdb命令介绍 运行控制

r(run)

 指令会一直执行程序,直到断点;还可以在任何时候重新启动程序

start

指令会执行程序至 main() 主函数的起始位置

n count

参数 count 表示单步执行多少行代码,默认为 1 行。

c

继续执行到断点

q

终止

s(step) count

单步;当包含函数时,会进入该函数内部,并在函数第一行代码处停止执行

u

快速运行完当前的循环体;

+某行代码的行号,执行至指定位置后停止

fi(finish )

执行函数到正常退出

return

立即结束执行当前函数并返回

jump

直接跳到 location 处的代码继续执行程序

l   显示代码

报 No such file or directory 错误解决方法:

解决: 将源代码文件拷贝相应目录(保持编译后源文件与可执行文件的相对位置)

结论: 使用gdb调试时,要将源文件,可执行文件一同复制过去

断点

GDB 调试器支持 3 种断点,分别为普通断点(用 break 命令创建)、观察断点(用 watch 命令建立)以及捕捉断点(用 catch 命令建立)

b  {filename:}[linenum/function] {if cond} 

举例:b function ;b linenum  ;b 7 if num>10

tbreak 程序暂停后,断点失效。使用方法与break一致

(w)watch cond  conde 指的就是要监控的变量或表达式

rwatch cond  read

awatch cond :read or write

断点管理

info break   info watchpoints  查看所有断点信息;   

clear 命令可以删除指定位置处的所有断点;clear 删除断点是基于行的,不是把所有的断点都删除

delete 命令(可以缩写为 d )通常用来删除所有断点,也可以删除指定编号的各类型断点

禁用断点可以使用 disable 命令,语法格式如下:

disable [breakpoints] [num...]

breakpoints 参数可有可无;num... 表示可以有多个参数,每个参数都为要禁用断点的编号。如果指定 num...,disable 命令会禁用指定编号的断点;反之若不设定 num...,则 disable 会禁用当前程序中所有的断点

对于禁用的断点,可以使用 enable 命令激活

内容查看

display num 程序停止自动打印

undisplay num...

delete display num…

参数 num... 表示目标变量或表达式的编号,编号的个数可以是多个

p num{=4   修改 num 的值为 4}

(gdb) p TestCase

报错解决方法 value of type `TEST_CASE' requires 70908 bytes, which is more than max-value-size

(gdb) set max-value-size unlimited

(gdb) p/x &TestCase.TestCaseData[0].Scale 可以查看变量地址

$21 = 0xaaaab8fcd354

(gdb) x/28xb $21 可以直接使用gdb给出的代表地址的变量

print高级用法

print [options --] [/fmt] expr

用 [ ] 括起来的部分是可选的,可以使用也可以省略

options 参数和 /fmt 或者 expr 之间,必须用--( 2 个 - 字符)分隔

print 命令不指定任何 options 参数时,print 和 /fmt 之间不用添加空格 :print/x num

-address on|off        查看某一指针变量的值时,是否同时打印其占用的内存地址,默认值为 on。

该选项等同于单独执行 set print address on|off 命令。

-array on|off        是否以便于阅读的格式输出数组中的元素,默认值为 off。

该选项等同于单独执行 set print array on|off 命令。

-array-indexes on|off对于非字符类型数组,在打印数组中每个元素值的同时,是否同时显示每个元素对应的数组下标,默认值为 off。该选项等同于单独执行 set print array-indexes on|off 命令。

-pretty on|off以便于阅读的格式打印某个结构体变量的值,默认值为 off。

该选项等同于单独执行 set print pretty on|off 命令。

@与::运算符 

int array[5] = {1,2,3,4};

如果我们想查看第 1 个元素和第 2 个元素的值,可以执行如下指令:

(gdb) print array[0]@2

$1 = {1, 2}

当程序中包含多个作用域不同但名称相同的变量或表达式时,可以借助::运算符明确指定要查看的目标变量或表达式。::运算符的语法格式如下:

(gdb) print file::variable

(gdb) print function::variable

 内存查看

examine 命令(简写是 x )来查看内存地址中的值。

x/

n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个单位的内容

f 表示显示的格式(f可选值)

x 按十六进制格式显示变量。

d 按十进制格式显示变量。

u 按十六进制格式显示无符号整型。

u 表示每个单位长度,默认为4字节(u可选值)

b 表示单字节

h 表示双字节

w 表示四字 节

g 表示八字节

其他指令

bt:backtrace,查看当前线程调用栈,顺序为自下往上的调用

frame 切换到当前调用栈的任意一个函数中

回车:重复执行上一次操作

info local以及其他gdb调试信息(快按两次Tab键会显示提示)

disassemble [Function] 反汇编

4、多线程调试

标号为1的线程是主线程

未指明线程时,命令作用于所有线程,停止时所有线程也会停。遇到当某个线程执行遇到断点时,GDB 调试器会自动将该线程作为当前线程

set scheduler-locking on 可以用来锁定当前线程,只观察这个线程的运行情况。当锁定这个线程时,其他线程就处于了暂停状态,也就是说你在当前线程执行 next、step、until、finish、return 命令时,其他线程是不会运行的

使用 thread 可以切换到对应的线程,然后使用 bt 命令可以查看对应线程从顶到底层的函数调用,以及上层调用下层对应的源码中的位置;可以使用 frame 切换到当前函数调用堆栈的任何一层函数调用中去,然后分析该函数执行逻辑;



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有